import s from './LogsViewer.module.less'
import { Editor } from '@renderer/Editor'
import { getFileLanguage } from '@renderer/Editor/get-file-language'
import { FileTree } from '@renderer/FileTree/FileTree'
import { useCallback, useEffect, useState } from 'react'

function filterByRawData(v: string, filter: string): string {
  const allLines = v.split('\n')
  return allLines.filter((l) => l.includes(filter)).join('\n')
}

function filterByRegExpStr(v: string, filter: string): string {
  const reg = new RegExp(filter, 'i')
  const allLines = v.split('\n')
  return allLines.filter((l) => reg.test(l)).join('\n')
}

function filterData(v: string, filter: string): string {
  if (filter.startsWith('#')) {
    return filterByRawData(v, filter.slice(1))
  } else {
    return filterByRegExpStr(v, filter)
  }
}

export function LogsViewer() {
  const [viewingDir, setViewingDir] = useState('')
  const [selectedFile, setSelectedFile] = useState('')
  const [fileValue, setFileValue] = useState('')
  const [viewValue, setViewValue] = useState('')
  const [filter, setFilter] = useState('')

  const onSelectFile = useCallback((filePath: string) => {
    setSelectedFile(filePath)
    window.api.readFile(filePath).then((d) => {
      setFileValue(d)
    })
  }, [])

  useEffect(() => {
    if (filter) {
      setViewValue('loading...')
    }
  }, [fileValue, filter])

  useEffect(() => {
    if (filter) {
      const timer = setTimeout(() => {
        try {
          setViewValue(filterData(fileValue, filter))
        } catch (err) {
          if (err instanceof Error) {
            setViewValue(err.message)
          }
        }
      }, 300)
      return () => {
        clearTimeout(timer)
      }
    } else {
      setViewValue(fileValue)
    }
    return void 0
  }, [filter, fileValue])

  return (
    <div className={s.logsViewer}>
      <div
        className={s.logsViewerSider}
        onDragOver={(ev) => ev.preventDefault()}
        onDrop={(ev) => {
          ev.preventDefault()
          const f = ev.dataTransfer.files
          if (f.length) {
            const file = f.item(0)
            if (file && 'path' in file && typeof file.path === 'string') {
              setViewingDir(file.path)
            }
          } else {
            const plainFile = ev.dataTransfer.getData('text/plain')
            if (plainFile) {
              setViewingDir(plainFile)
            }
          }
        }}
      >
        {viewingDir ? (
          <FileTree filePath={viewingDir} selectedFile={selectedFile} onClickFile={onSelectFile} />
        ) : (
          <div className={s.logsViewerDirBox}>拖拽文件夹或者文件到这里</div>
        )}
      </div>
      <div className={s.logsViewerContent}>
        <div className={s.logsViewerFilter}>
          <input
            className={s.logsViewerFilterInput}
            value={filter}
            placeholder="过滤表达式 (鼠标右键清空过滤条件)"
            onChange={(ev) => setFilter(ev.target.value)}
            onContextMenu={() => {
              setFilter('')
            }}
          ></input>
        </div>
        <div className={s.logsViewerTextPreview}>
          <Editor readonly={true} value={viewValue} lang={getFileLanguage(selectedFile)} />
        </div>
      </div>
    </div>
  )
}
